今天將探討MySQL的CPU使用量與Memory使用量.之前已經介紹了
系統的CPU使用量與Memory使用量的獲取及繪圖.但若要對某一特定
程式如MySQL或Apache等主要服務作監控,要如何作呢?
們可以利用top或是pidstat等指令來間接獲取,較為簡便.以下
將使用top指令的功能,來對Mysql Daemon的CPU使用量及Memory使用量,
獲取及儲存到RRD,再透過RRD的繪圖功能,將這兩個數據同時繪製在圖形上,
可以獲得一個直觀的概念,同樣的方法在昨天的 溫度-風扇轉速 對照圖,
也使用過.
首先是建立rrd的程式.
#!/usr/bin/env python
# ------------------------
# Python RRDTool MySQL
# MySQL CPU & Memory
# create rrd file
# -----------------------
import rrdtool
rrdtool.create(
'mysql1.rrd', '--step', '60',
'DS:cpu:GAUGE:120:0:U',
'DS:mem:GAUGE:120:0:U',
'RRA:AVERAGE:0.5:1:2880',
'RRA:AVERAGE:0.5:30:672',
'RRA:AVERAGE:0.5:60:744',
'RRA:AVERAGE:0.5:720:732',
'RRA:MAX:0.5:1:2880',
'RRA:MAX:0.5:30:672',
'RRA:MAX:0.5:60:744',
'RRA:MAX:0.5:720:732',
'RRA:MIN:0.5:1:2880',
'RRA:MIN:0.5:30:672',
'RRA:MIN:0.5:60:744',
'RRA:MIN:0.5:720:732',
'RRA:LAST:0.5:1:2880',
'RRA:LAST:0.5:30:672',
'RRA:LAST:0.5:60:744',
'RRA:LAST:0.5:720:732')
再來是獲取及儲存的程式.
#!/usr/bin/env python
# --------------------
# Python RRDTool MySQL
# CPU & Memory
# update rrd file
# --------------------
import time
import subprocess
import rrdtool
def update_rrd():
# Get pid of mysqld
output = subprocess.check_output('ps aux | grep mysqld', shell=True,)
eachlines = output.splitlines()
first = eachlines[0]
pid = first.split()[1]
# Using Top
topcmd = 'top -b -n 1 -p ' + pid
output = subprocess.check_output(topcmd, shell=True,)
eachlines = output.splitlines()
eachlines = eachlines[:-1]
for line in eachlines:
data = line.split()
if len(data) > 0:
if data[0] == 'Mem:':
totalmem = int(data[1][:-1])
if data[0] == pid:
mysql_cpu = float(data[8])
mysql_mem_per = float(data[9])
#
mem_usage = totalmem * mysql_mem_per / 100
rrdtool.update('mysql1.rrd', 'N:' + `mysql_cpu` + ':' + `mem_usage`)
#
if __name__ == '__main__':
while 1:
update_rrd()
time.sleep(59)
注意到這裡讓程式 sleep 59秒,之前其他類似的程式都是sleep 60秒,為何這裡要
sleep 59秒? 因為我們使用指令來獲取CPU使用量,需要有間隔,top程式才能以
兩個時刻CPU計數器的差異值,換算出CPU使用量,top程式設定間隔1秒,所以後面
的sleep 只需59秒.
接著是繪圖的程式.
#!/usr/bin/env python
# ---------------------------
# Python RRDTool
# MySQL CPU & Memory Data
# Create Image from rrd file
# ---------------------------
import rrdtool
import datetime
def mysql_graph(rrdfile, period):
timenow = datetime.datetime.now()
disptime = datetime.datetime.strftime(timenow, '%Y-%m-%d %H-%M-%S')
title = 'MySQL_CPU_Memory_%s' % period
filename = title + '.png'
# -------------------
cpu = 'DEF:cpu=%s:cpu:AVERAGE' % rrdfile
mem = 'DEF:mem=%s:mem:AVERAGE' % rrdfile
mem_mega = 'CDEF:mem_mega=mem,1024,/'
mega100 = 'CDEF:mega100=mem_mega,100,/'
# -------------------
if period == 'yesterday':
start = 'end-1d'
end = '00:00'
if period == 'today':
start = '00:00'
end = '23:59'
if period == '2h':
start = '-2h'
end = 'now'
rrdtool.graph(
filename,
'--start', start,
'--end', end,
'--title', title,
'-a', 'PNG',
'-W', 'Hitomitanaka for ITHelp',
'--slope-mode',
'--vertical-label=CPU Percent',
'--rigid',
'--lower-limit', '0',
'--width', '500',
'--height', '150',
'--right-axis', '100:0',
'--right-axis-label=Mega',
'--x-grid', 'HOUR:1:HOUR:2:HOUR:2:0:%H',
'--alt-y-grid',
'--color', 'BACK#000000',
'--color', 'CANVAS#000000',
'--color', 'FONT#FFF978',
'--font=LEGEND:7',
'--font', 'TITLE:8:',
'--font', 'UNIT:7:',
'--font', 'WATERMARK:9',
# ---------------------------------
cpu,
mem,
mem_mega,
mega100,
#----------------------------------
'AREA:mega100#EEEE0088:Memory Usage',
'GPRINT:mem_mega:LAST: Current\\: %.01lf',
'GPRINT:mem_mega:AVERAGE: Average\\: %.01lf',
'GPRINT:mem_mega:MIN: Min\\: %.01lf',
'GPRINT:mem_mega:MAX: Max\\: %.01lf\\n',
'LINE2:cpu#FF32B1:CPU Utilization',
'GPRINT:cpu:LAST: Current\\: %.01lf',
'GPRINT:cpu:AVERAGE: Average\\: %.01lf',
'GPRINT:cpu:MIN: Min\\: %.01lf',
'GPRINT:cpu:MAX: Max\\: %.01lf\\n',
'COMMENT:\t\t\t\t\tUpdate Time %s' % disptime)
#
if __name__ == '__main__':
mysql_graph('mysql1.rrd', 'today')
mysql_graph('mysql1.rrd', '2h')
使用簡易的壓力測試,然後繪製出壓力測試期間,CPU使用量與Memory使用量對照圖.
前面三張是壓力測試初期,可以很明顯看到記憶體用量變化不大,CPU用量隨著
壓力測試運作而有高低起伏,因為此簡易壓力測試程式,只有登入一個session,
此期間筆者也另外登入一個session,所以可以看到Memory使用量略有增加.
第4張圖,CPU使用量達到67,這時候圖形比例調整的關係,此一峰值很顯著,
但是記憶體的圖形相對就變得不明顯了.第5圖是後續的圖形,如同第4張圖
會受到峰值影響.
我們在利用RRD繪圖時,要注意此一情形,當有特別高或低的值出現時,整體都會受到
影響,所以我們可以再選擇繪圖時段,如1~3圖,以利對照,或是可以另行繪製獨立的圖形.
接著看第6張圖,是使用全天區間,這時候CPU的峰值卻回報為23 !?
為何是這樣呢?
這就要了解RRD的原理.我們一開始建立rrd的時候,有設定1分鐘的資料會存放2880筆,
相當於2天.
請看第7張圖形,在隔天採用寬度1440來繪製昨天的圖形,因為資料能夠達到每分鐘
一筆,與1440是符合的,所以沒有任何變化,也是繪製與回報CPU使用量為67.
但是第6張圖是用寬度500來繪製,當1440筆資料以500寬度來匯製,會大約採用3分鐘
區間來平均後得到估計值,故在第6張圖回報峰值為23.
RRD使用廣泛,適合使用數據的長時間觀察,會逐漸的平均,隨著時間流逝,
數值是用平均的;而且圖形的大小,也會影響其回報數據.
當我們進行測試需要較精細的數值時,需要將繪圖區間縮小,繪製後再備份.
或是採用筆者之前介紹的方法,將資料存放到MySQL Archive引擎的Table中,
再利用其他繪圖的程式,才不致受到RRD的逐漸平均的影響.
RRD使用廣泛,在許多系統均有利用,但是圖形大小與區間多為固定,
我們若能夠了解其特性,自行繪製圖形,當能對系統狀態有更深入的了解.